#ifndef EQUATIONSOLVER
#define EQUATIONSOLVER
#include <cmath>

class Function {
public:
    // 纯虚函数，用于计算函数值
    virtual double operator()(double x) const = 0;
    
    // 虚函数，用于计算函数的导数值
    virtual double derivative(double x) const = 0;
};

class EquationSolver{
protected:
    const Function & F;  // 引用传入的函数对象
public:
    EquationSolver(const Function& F) : F(F) {}  // 构造函数，初始化函数对象的引用
    virtual double solve() = 0;   // 纯虚函数，用于计算方程的解
    virtual ~EquationSolver() {}   // 虚析构函数，确保子类可以正确析构
};

class Bisection_Method : public EquationSolver {
private:
    double a, b;
    double eps, delta;
    int Maxiter;
public:
    Bisection_Method(const Function &F, double a, double b, 
        double eps = 1e-7, double delta = 1e-6, int Maxiter = 50) :
        EquationSolver(F), a(a), b(b), eps(eps), delta(delta), Maxiter(Maxiter) {}
    
    virtual double solve() override{
        double c; 
        for (int i = 0; i < Maxiter; i++) {
            c = (a + b) / 2;
            if (fabs(F(c)) < eps || (b-a)<delta) return c;
            if (F(a) * F(c) < 0) b = c;
            else a = c;
        }
        return (a + b) / 2;
    }
};

class Newton_Method : public EquationSolver {
private:
    double x0;
    double eps;
    int Maxiter;
public:
    Newton_Method(const Function &F, double x0, 
        double eps = 1e-7, double Maxiter = 8) :
        EquationSolver(F), x0(x0), eps(eps), Maxiter(Maxiter){}
    
    virtual double solve() override {
        double x = x0, h ,df;
        for (int i = 0; i < Maxiter; i++) {
            df = F.derivative(x);
            h = F(x);
            if (fabs(h) < eps) return x;
            x = x - h/df;
        }
        return x;
    }
};

class Secant_Method : public EquationSolver {
private:
    double x0, x1;
    double eps, delta;
    int Maxiter;

public:
    Secant_Method(const Function& F, double x0, double x1, double eps = 1e-7, double delta = 1e-6, int Maxiter = 50)
        : EquationSolver(F), x0(x0), x1(x1), eps(eps), delta(delta) , Maxiter(Maxiter) {}

    virtual double solve() override {
        double x = x1, y = x0, h;
        for (int i = 0; i < Maxiter; i++) {
            if (fabs(F(x))< eps || fabs(y-x) < delta ) return x; 
            h = F(x) * (x - y) / (F(x) - F(y));
            y = x;
            x = x-h;
        }
        return x;
    }
};

#endif